'''
你好，请编写一个包含如下功能的python-wxpython程序
    1.有功能选择页面，选择页面为每个功能为一个按钮
    2.有“程序建议”，“售票”，“预订票”，“退票”，“更改票信息”，“导出凭证”，“生成验证QR码”，“使用QR码核销”，“票号核销”，“姓名查票”，“票号查票”等功能，越多越好，发散思维
    3.程序应有登录页面，登录后可使用功能
    4.可使用MySQL
    5.一张票应有如下信息：姓名，票号，票型，检验码，操作员，入园日期，应付价格，优惠价格，实付价格，状态
    6.验证QR码应包含5.的所有信息
    7.数据库应有如下几个表：'ticketinfo','user'
        7.1 ticketinfo用来存储所有已售出的票的信息
        7.2 user用作存储能登录软件的账号的信息
    8.应分为后端flask部分和前端wxpython部分
    9.售票、预订票时应要求输入：姓名，应付价格。要求选择：票型，入园日期。根据票型设置“应付价格”，优惠价格，实付价格：普通票，优惠0，实付=应付；特别票，优惠50%，实付=应付×0.5。自动记录操作账号为操作员项，状态为正常。自动生成票号（为数据库中上一票的票号+1），自动生成验证码（为票号的后三位+随机5个数字）
    10.退票需输入：姓名，入园日期，票号，票型，检验码
    11.更改票信息即使用票号、验证码作为验证，修改姓名或入园日期
    12.到处凭证就是将票的所有信息导出为txt
    13.生成验证QR即将票的信息以“姓名@入园日期@检验码”为内容生成QR
    14.使用QR码核销就是把QR内容所对应的票的状态改为已使用
    15.票号核销即把输入的姓名，验证码所对应的票的状态改为已使用
谢了
写完python程序！不要鬼话连篇说篇幅限制无法提供
'''

'''
你好，请编写一个包含如下功能的python-wxpython程序
    1.有功能选择页面，选择页面为每个功能为一个按钮
    2.有“售票”，“退票”，“更改票信息”“票号核销”，“查票”
    3.程序应有登录页面，登录后可使用功能
    4.用MySQL
    5.一张票应有如下信息：姓名，票号，票型，检验码，操作员，入园日期，应付价格，优惠价格，实付价格，状态
    6.数据库应有如下几个表：'ticketinfo','user'
        6.1 ticketinfo用来存储所有已售出的票的信息
        6.2 user用作存储能登录软件的账号的信息
    7.售票时应要求输入：姓名，应付价格。要求选择：票型，入园日期。根据票型设置“应付价格”，优惠价格，实付价格：普通票，优惠0，实付=应付；特别票，优惠50%，实付=应付×0.5。自动记录操作账号为操作员项，状态为正常。自动生成票号（为数据库中上一票的票号+1），自动生成验证码（为票号的后三位+随机5个数字）
    8.退票需输入：姓名，入园日期，票号，票型，检验码
    9.更改票信息即使用票号、验证码作为验证，修改姓名或入园日期
    10.票号核销即把输入的姓名，验证码所对应的票的状态改为已使用
    11.将所有功能的函数内容尽你的所有想象补全，哪怕错了也没关系
    12.所有内容应在GUI内体现
谢了
写完python程序！不要鬼话连篇说篇幅限制无法提供
'''
'''
你好，请编写一个包含如下功能的python-wxpython程序，并给出sql指令文件内容。
    1.有功能选择页面，选择页面为每个功能为一个按钮
    2.有“程序建议”，“售票”，“预订票”，“退票”，“更改票信息”，“导出凭证”，“生成验证QR码”，“使用QR码核销”，“票号核销”，“姓名查票”，“票号查票”等功能，越多越好，发散思维
    3.程序应有登录页面，登录后可使用功能
    4.可使用MySQL
    5.一张票应有如下信息：姓名，票号，票型，检验码，操作员，入园日期，应付价格，优惠价格，实付价格，状态
    6.验证QR码应包含5.的所有信息
    7.数据库应有如下几个表：'ticketinfo','user'
        7.1 ticketinfo用来存储所有已售出的票的信息
        7.2 user用作存储能登录软件的账号的信息
    8.应分为后端flask部分和前端wxpython部分
    9.售票、预订票时应要求输入：姓名，应付价格。要求选择：票型，入园日期。根据票型设置“应付价格”，优惠价格，实付价格：普通票，优惠0，实付=应付；特别票，优惠50%，实付=应付×0.5。自动记录操作账号为操作员项，状态为正常。自动生成票号（为数据库中上一票的票号+1），自动生成验证码（为票号的后三位+随机5个数字）
    10.退票需输入：姓名，入园日期，票号，票型，检验码
    11.更改票信息即使用票号、验证码作为验证，修改姓名或入园日期
    12.到处凭证就是将票的所有信息导出为txt
    13.生成验证QR即将票的信息以“姓名@入园日期@检验码”为内容生成QR
    14.使用QR码核销就是把QR内容所对应的票的状态改为已使用
    15.票号核销即把输入的姓名，验证码所对应的票的状态改为已使用
谢了
写完python程序！
    '''

import wx
import os
import pymysql
import random
import qrcode
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart


# 创建数据库连接
db = pymysql.connect(
    host="localhost",
    user="root",
    password="aaa1234512345",
    database="ticket_system"
)

# 创建游标对象
cursor = db.cursor()

# 创建登录页面
class LoginPage(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="登录页面", size=(300, 200))
        panel = wx.Panel(self)

        self.username_label = wx.StaticText(panel, label="用户名:")
        self.username_text = wx.TextCtrl(panel)
        self.password_label = wx.StaticText(panel, label="密码:")
        self.password_text = wx.TextCtrl(panel, style=wx.TE_PASSWORD)
        self.login_button = wx.Button(panel, label="登录")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.username_label, 0, wx.ALL, 5)
        sizer.Add(self.username_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.password_label, 0, wx.ALL, 5)
        sizer.Add(self.password_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.login_button, 0, wx.ALL | wx.CENTER, 5)

        panel.SetSizer(sizer)

        self.login_button.Bind(wx.EVT_BUTTON, self.on_login)

    def on_login(self, event):
        username = self.username_text.GetValue()
        password = self.password_text.GetValue()

        # 在此处验证用户名和密码是否正确
        query = "SELECT * FROM user WHERE username = %s AND password = %s"
        values = (username, password)
        cursor.execute(query, values)
        result = cursor.fetchone()

        if result:
            self.Close()
            main_page = MainPage()
            main_page.Show()
        else:
            wx.MessageBox("用户名或密码错误！", "错误", wx.OK | wx.ICON_ERROR)


# 创建主页面
class MainPage(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="主页面", size=(600, 400))
        panel = wx.Panel(self)

        self.function_list = [
            "售票",
            "退票",
            "核销",
            "更改票购信息",
            "导出凭证",
            "生成验证QR码",
            "查票"
        ]

        self.function_buttons = []
        for function in self.function_list:
            button = wx.Button(panel, label=function)
            self.function_buttons.append(button)

        sizer = wx.BoxSizer(wx.VERTICAL)
        for button in self.function_buttons:
            sizer.Add(button, 0, wx.ALL | wx.EXPAND, 5)

        panel.SetSizer(sizer)

        for button in self.function_buttons:
            button.Bind(wx.EVT_BUTTON, self.on_function_select)

    def on_function_select(self, event):
        selected_function = event.GetEventObject().GetLabel()

        if selected_function == "售票":
            sell_ticket_page = SellTicketPage()
            sell_ticket_page.Show()
        elif selected_function == "查票":
            check_ticket_page = CheckTicketPage()
            check_ticket_page.Show()
        elif selected_function == "退票":
            tuipiao_page = tuipiao()
            tuipiao_page.Show()
        elif selected_function == "核销":
            checkin_page = checkin()
            checkin_page.Show()
        elif selected_function == "更改票购信息":
            gaii_page = gaii()
            gaii_page.Show()
        elif selected_function == "导出凭证":
            ExportVoucherFrame_page = ExportVoucherFrame()
            ExportVoucherFrame_page.Show()
        elif selected_function == "生成验证QR码":
            QRCodeFrame_page = QRCodeFrame()
            QRCodeFrame_page.Show()

class SellTicketPage(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="售票页面", size=(400, 470))
        panel = wx.Panel(self)

        self.name_label = wx.StaticText(panel, label="姓名:")
        self.name_text = wx.TextCtrl(panel)

        self.ticket_type_label = wx.StaticText(panel, label="票型:")
        self.ticket_type_choice = wx.Choice(panel, choices=["普通票", "特别票"])
        self.entry_date_label = wx.StaticText(panel, label="入园日期:")
        self.entry_date_text = wx.TextCtrl(panel)
        self.payable_price_label = wx.StaticText(panel, label="应付价格:")
        self.payable_price_text = wx.TextCtrl(panel)
        self.discount_rate_label = wx.StaticText(panel, label="折扣率:")
        self.discount_rate_text = wx.TextCtrl(panel)
        self.email_label = wx.StaticText(panel, label="联系邮箱:")
        self.email_text = wx.TextCtrl(panel)
        self.sell_button = wx.Button(panel, label="售票")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.name_label, 0, wx.ALL, 5)
        sizer.Add(self.name_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.ticket_type_label, 0, wx.ALL, 5)
        sizer.Add(self.ticket_type_choice, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.entry_date_label, 0, wx.ALL, 5)
        sizer.Add(self.entry_date_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.payable_price_label, 0, wx.ALL, 5)
        sizer.Add(self.payable_price_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.discount_rate_label, 0, wx.ALL, 5)
        sizer.Add(self.discount_rate_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.email_label, 0, wx.ALL, 5)
        sizer.Add(self.email_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.sell_button, 0, wx.ALL | wx.CENTER, 5)

        panel.SetSizer(sizer)

        self.sell_button.Bind(wx.EVT_BUTTON, self.on_sell)
    
    def send_strn(email,name,entry_date):
        #163邮箱服务器地址
        mail_host = 'smtp.163.com'  
        #163用户名
        mail_user = 'nninnos'  
        #密码(部分邮箱为授权码) 
        mail_pass = 'AWWMKIOXSQOFDUAH'   
        #邮件发送方邮箱地址
        sender = 'nninnos@163.com'

        query = "SELECT * FROM ticketinfo WHERE name = %s AND entry_date = %s;"
        values = (name,entry_date)
        cursor.execute(query, values)
        result = cursor.fetchone()

        #设置email信息
        content="尊敬的游客%s：\n     您好！\n    我们很高兴地通知您，您已经成功通过Byinfo购买了门票。我们已经确认您的订单，并将为您安排好一切。\n    请注意，您的订单信息会稍后发送给您。如果您需要帮助或有任何疑问，请随时与我们联系。\n    如未购买门票，收到此邮件，请您忽视它。\n    感谢您选择我们的服务，我们期待着您在乐园中度过愉快的时光。\n    再次感谢您的信任和支持！\n    Byinfo\n\n"+f"票号: {result[2]}\n姓名: {result[1]}\n票型: {result[3]}\n检验码: {result[4]}\n操作员: {result[5]}\n入园日期: {result[6]}\n应付价格: {result[7]}\n优惠价格: {result[8]}\n实付价格: {result[9]}"
        #邮件内容设置
        message = MIMEMultipart('related')
        message.attach(MIMEText((content%name),'plain','utf-8'))
        cur_path = os.path.dirname(os.path.realpath(__file__))
        qr_data = f"票号: {result[2]}\n姓名: {result[1]}\n票型: {result[3]}\n检验码: {result[4]}\n操作员: {result[5]}\n入园日期: {result[6]}\n应付价格: {result[7]}\n优惠价格: {result[8]}\n实付价格: {result[9]}"
        qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
        qr.add_data(qr_data)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")
        img_path = './/%s_qr.png'%('data')
        img.save(img_path)
        # 二进制读取图片
        image_data = open('.//data_qr.png','rb')
        # 设置读取获取的二进制数据
        message_image = MIMEImage(image_data.read())
        # 关闭刚才打开的文件
        image_data.close()
        # 添加图片文件到邮件信息当中去
        message.attach(message_image)
       #邮件主题       
        message['Subject'] = '购票成功' 
        #发送方信息
        message['From'] = sender 
        #接受方信息     
        message['To'] = ''.join(email)

        #登录并发送邮件
        try:
            smtpObj = smtplib.SMTP() 
            #连接到服务器
            smtpObj.connect(mail_host,25)
            #登录到服务器
            smtpObj.login(mail_user,mail_pass) 
            #发送
            smtpObj.sendmail(sender,email,message.as_string()) 
            #退出
            smtpObj.quit() 
            print('success')
        except smtplib.SMTPException as e:
            print('error',e) #打印错误

    def on_sell(self, event):
        name = self.name_text.GetValue()
        ticket_type = self.ticket_type_choice.GetStringSelection()
        entry_date = self.entry_date_text.GetValue()
        payable_price = int(self.payable_price_text.GetValue())
        discount_rate = self.discount_rate_text.GetValue()
        email = str(self.email_text.GetValue())
        # 自动生成票号
        last_ticket_number = self.get_last_ticket_number()
        ticket_number = str(int(last_ticket_number) + 1)

        # 自动生成验证码
        verification_code = ticket_number[-3:] + str(random.randint(10000, 99999))

        # 根据票型设置应付价格、优惠价格和实付价格
        discount_price = str(float(payable_price) - float(payable_price) * float(discount_rate))
        actual_price = str(payable_price - float(discount_price))
        operator='root'
        # 在此处执行售票操作，将票信息插入到ticketinfo表中
        query = "INSERT INTO ticketinfo (name, ticket_number, ticket_type, verification_code, operator, entry_date, payable_price, discount_price, actual_price,status,email,discount_rate) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,%s,%s)"
        values = (name, ticket_number, ticket_type, verification_code, operator, entry_date, payable_price, discount_price, actual_price, "normal",email,discount_rate)
        cursor.execute(query, values)
        db.commit()
        SellTicketPage.send_strn(email,name,entry_date)
        wx.MessageBox("售票成功！", "成功", wx.OK | wx.ICON_INFORMATION)
        self.Close()

    def get_last_ticket_number(self):
        # 从数据库中获取上一票的票号
        query = "SELECT ticket_number FROM ticketinfo ORDER BY ticket_number DESC LIMIT 1"
        cursor.execute(query)
        result = cursor.fetchone()
        if result:
            return result[0]
        else:
            return "0"

class tuipiao(wx.Frame):
    def __init__(self,):
#        super(tuipiao, self).__init__(title='退票页面', size=(400, 300))
        wx.Frame.__init__(self, None, title="退票页面", size=(400, 400))

        self.panel = wx.Panel(self)
        
        self.name_label = wx.StaticText(self.panel, label="姓名:")
        self.name_text = wx.TextCtrl(self.panel)
        
        self.date_label = wx.StaticText(self.panel, label="入园日期:")
        self.date_text = wx.TextCtrl(self.panel)
        
        self.ticket_label = wx.StaticText(self.panel, label="票号:")
        self.ticket_text = wx.TextCtrl(self.panel)
        
        self.ticket_type_label = wx.StaticText(self.panel, label="票型:")
        self.ticket_type_text = wx.TextCtrl(self.panel)
        
        self.verification_label = wx.StaticText(self.panel, label="检验码:")
        self.verification_text = wx.TextCtrl(self.panel)
        
        self.refund_button = wx.Button(self.panel, label="退票")
        self.refund_button.Bind(wx.EVT_BUTTON, self.on_refund)
        
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.name_label, 0, wx.ALL, 5)
        self.sizer.Add(self.name_text, 0, wx.ALL, 5)
        self.sizer.Add(self.date_label, 0, wx.ALL, 5)
        self.sizer.Add(self.date_text, 0, wx.ALL, 5)
        self.sizer.Add(self.ticket_label, 0, wx.ALL, 5)
        self.sizer.Add(self.ticket_text, 0, wx.ALL, 5)
        self.sizer.Add(self.ticket_type_label, 0, wx.ALL, 5)
        self.sizer.Add(self.ticket_type_text, 0, wx.ALL, 5)
        self.sizer.Add(self.verification_label, 0, wx.ALL, 5)
        self.sizer.Add(self.verification_text, 0, wx.ALL, 5)
        self.sizer.Add(self.refund_button, 0, wx.ALL, 5)
        
        self.panel.SetSizer(self.sizer)
        self.Show()
    
    def on_refund(self, event):
        name = self.name_text.GetValue()
        date = self.date_text.GetValue()
        ticket_number = self.ticket_text.GetValue()
        ticket_type = self.ticket_type_text.GetValue()
        verification_code = self.verification_text.GetValue()
        
        
        # 执行退票操作
        query = ("UPDATE ticketinfo SET status = 'refund' WHERE name = %s AND entry_date = %s "
                 "AND ticket_number = %s AND ticket_type = %s AND verification_code = %s")
        data = (name, date, ticket_number, ticket_type, verification_code)
        cursor.execute(query, data)
        
        wx.MessageBox("退票成功！", "退票")
        self.Close()
    
    def clear_fields(self):
        self.name_text.SetValue("")
        self.date_text.SetValue("")
        self.ticket_text.SetValue("")
        self.ticket_type_text.SetValue("")
        self.verification_text.SetValue("")


class checkin(wx.Frame):
    def __init__(self,):
#        super(TicketVerification, self).__init__(parent, title=title, size=(400, 300))
        wx.Frame.__init__(self, None, title="核销页面", size=(400, 400))
        self.panel = wx.Panel(self)

        self.ticket_number_label = wx.StaticText(self.panel, label="票号:")
        self.ticket_number_text = wx.TextCtrl(self.panel)

        self.entry_date_label = wx.StaticText(self.panel, label="入园日期:")
        self.entry_date_text = wx.TextCtrl(self.panel)

        self.verification_code_label = wx.StaticText(self.panel, label="验证码:")
        self.verification_code_text = wx.TextCtrl(self.panel)

        self.verify_button = wx.Button(self.panel, label="核销")
        self.verify_button.Bind(wx.EVT_BUTTON, self.on_verify)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.ticket_number_label, 0, wx.ALL, 5)
        sizer.Add(self.ticket_number_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.entry_date_label, 0, wx.ALL, 5)
        sizer.Add(self.entry_date_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.verification_code_label, 0, wx.ALL, 5)
        sizer.Add(self.verification_code_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.verify_button, 0, wx.ALL | wx.CENTER, 5)

        self.panel.SetSizer(sizer)

    def on_verify(self, event):
        ticket_number = self.ticket_number_text.GetValue()
        entry_date = self.entry_date_text.GetValue()
        verification_code = self.verification_code_text.GetValue()
    # 查询票务信息
        query = "SELECT status FROM ticketinfo WHERE ticket_number = %s AND entry_date = %s AND verification_code = %s"
        values = (ticket_number, entry_date, verification_code)
        cursor.execute(query, values)
        result = cursor.fetchone()
        if result is None:
            wx.MessageBox("不存在该票！", "提示", wx.OK | wx.ICON_INFORMATION)
        else:
            status = result[0]
            if str(status) == 'refund':
                wx.MessageBox("该票已退票！", "提示", wx.OK | wx.ICON_INFORMATION)
            else:
                # 核销票务信息
                query = "UPDATE ticketinfo SET status = 'used' WHERE ticket_number = %s AND entry_date = %s AND verification_code = %s"
                values = (ticket_number, entry_date, verification_code)
                cursor.execute(query, values)
                db.commit()
                wx.MessageBox("核销成功！", "提示", wx.OK | wx.ICON_INFORMATION)

        app = wx.App()
        app.MainLoop()

class gaii(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="更改信息页面", size=(400, 400))
        self.InitUI()
        self.Centre()
        self.Show()

    def InitUI(self):
        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)

        # 创建控件
        self.ticket_no_label = wx.StaticText(panel, label='票号')
        self.ticket_no_text = wx.TextCtrl(panel)
        self.verify_code_label = wx.StaticText(panel, label='验证码')
        self.verify_code_text = wx.TextCtrl(panel)
        self.name_label = wx.StaticText(panel, label='姓名')
        self.name_text = wx.TextCtrl(panel)
        self.date_label = wx.StaticText(panel, label='入园日期')
        self.date_text = wx.TextCtrl(panel)
        self.change_button = wx.Button(panel, label='更改票信息')

        # 添加控件到布局
        vbox.Add(self.ticket_no_label, flag=wx.ALL, border=10)
        vbox.Add(self.ticket_no_text, flag=wx.EXPAND | wx.ALL, border=10)
        vbox.Add(self.verify_code_label, flag=wx.ALL, border=10)
        vbox.Add(self.verify_code_text, flag=wx.EXPAND | wx.ALL, border=10)
        vbox.Add(self.name_label, flag=wx.ALL, border=10)
        vbox.Add(self.name_text, flag=wx.EXPAND | wx.ALL, border=10)
        vbox.Add(self.date_label, flag=wx.ALL, border=10)
        vbox.Add(self.date_text, flag=wx.EXPAND | wx.ALL, border=10)
        vbox.Add(self.change_button, flag=wx.ALL | wx.ALIGN_CENTER, border=10)

        panel.SetSizer(vbox)

        # 绑定按钮事件
        self.change_button.Bind(wx.EVT_BUTTON, self.OnChangeButton)

    def OnChangeButton(self, event):
        ticket_no = self.ticket_no_text.GetValue()
        verify_code = self.verify_code_text.GetValue()
        name = self.name_text.GetValue()
        date = self.date_text.GetValue()

        # 验证票号和验证码是否匹配
        if self.VerifyTicket(ticket_no, verify_code):
            # 更新票信息
            self.UpdateTicketInfo(ticket_no, name, date)
            wx.MessageBox('票信息已更改！', '提示', wx.OK | wx.ICON_INFORMATION)
        else:
            wx.MessageBox('票号和验证码不匹配，请重新输入！', '错误', wx.OK | wx.ICON_ERROR)

    def VerifyTicket(self, ticket_no, verify_code):
        # 查询票号和验证码是否匹配
        query = "SELECT * FROM ticketinfo WHERE ticket_number = %s AND verification_code = %s"
        cursor.execute(query, (ticket_no, verify_code))
        result = cursor.fetchone()
        return result is not None

    def UpdateTicketInfo(self, ticket_no, name, date):
        # 更新票信息
        query = "UPDATE ticketinfo SET name = %s, entry_date = %s WHERE ticket_number = %s"
        cursor.execute(query, (name, date, ticket_no))
        db.commit()

class ExportVoucherFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="导出凭证页面", size=(400, 400))
        
        panel = wx.Panel(self)
        
        self.name_label = wx.StaticText(panel, label="姓名:")
        self.name_text = wx.TextCtrl(panel)
        
        self.date_label = wx.StaticText(panel, label="入园日期:")
        self.date_text = wx.TextCtrl(panel)
        
        self.code_label = wx.StaticText(panel, label="验证码:")
        self.code_text = wx.TextCtrl(panel)
        
        export_button = wx.Button(panel, label="导出凭证")
        export_button.Bind(wx.EVT_BUTTON, self.export_voucher)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.name_label, 0, wx.ALL, 5)
        sizer.Add(self.name_text, 0, wx.EXPAND|wx.ALL, 5)
        sizer.Add(self.date_label, 0, wx.ALL, 5)
        sizer.Add(self.date_text, 0, wx.EXPAND|wx.ALL, 5)
        sizer.Add(self.code_label, 0, wx.ALL, 5)
        sizer.Add(self.code_text, 0, wx.EXPAND|wx.ALL, 5)
        sizer.Add(export_button, 0, wx.ALL, 5)
        
        panel.SetSizer(sizer)
        self.Show()
    
    def export_voucher(self, event):
        name = self.name_text.GetValue()
        date = self.date_text.GetValue()
        code = self.code_text.GetValue()
                
        # 查询票的信息
        query = "SELECT * FROM ticketinfo WHERE name = %s AND entry_date = %s AND verification_code = %s"
        cursor.execute(query, (name, date, code))
        tickets = cursor.fetchall()

        # 导出凭证到txt文件
        if tickets:
            with open(f'D:/voucher.txt', 'w') as file:
                for ticket in tickets:
                    file.write(f"姓名: {ticket[1]}\n")
                    file.write(f"票号: {ticket[2]}\n")
                    file.write(f"票型: {ticket[3]}\n")
                    file.write(f"检验码: {ticket[4]}\n")
                    file.write(f"操作员: {ticket[5]}\n")
                    file.write(f"入园日期: {ticket[6]}\n")
                    file.write(f"应付价格: {ticket[7]}\n")
                    file.write(f"优惠价格: {ticket[8]}\n")
                    file.write(f"实付价格: {ticket[9]}\n")
                    file.write(f"状态: {ticket[10]}\n")
                    file.write(f"邮箱: {ticket[11]}\n")
                    file.write(f"折扣率: {ticket[12]}\n")
                    file.write("\n")
            
            wx.MessageBox("凭证已成功导出到voucher.txt文件！", "导出成功", wx.OK | wx.ICON_INFORMATION)
        else:
            wx.MessageBox("未找到符合条件的票信息！", "导出失败", wx.OK | wx.ICON_ERROR)

class QRCodeFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="QR生成页面", size=(400, 400))
        
        panel = wx.Panel(self)
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        
        self.ticket_number_label = wx.StaticText(panel, label="票号:")
        self.ticket_number_text = wx.TextCtrl(panel)
        vbox.Add(self.ticket_number_label, flag=wx.ALL, border=10)
        vbox.Add(self.ticket_number_text, flag=wx.EXPAND|wx.ALL, border=10)
        
        self.generate_button = wx.Button(panel, label="生成QR码")
        self.generate_button.Bind(wx.EVT_BUTTON, self.on_generate)
        vbox.Add(self.generate_button, flag=wx.ALIGN_CENTER|wx.ALL, border=10)
        
        panel.SetSizer(vbox)
        
    def on_generate(self,event):
        ticket_number = self.ticket_number_text.GetValue()
        verification_code = self.get_verification_code(ticket_number)[0]
        name = self.get_verification_code(ticket_number)[1]
        
        if verification_code is not None:
            qr_data = f"{name}@{ticket_number}@{verification_code}"
            qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
            qr.add_data(qr_data)
            qr.make(fit=True)
            
            img = qr.make_image(fill_color="black", back_color="white")
            img_path = f"D:/verification_qr.png"
            img.save(img_path)
            
            wx.MessageBox("QR码生成成功！", "提示", wx.OK | wx.ICON_INFORMATION)
        else:
            wx.MessageBox("无法找到对应的验证码！", "错误", wx.OK | wx.ICON_ERROR)
        
    def get_verification_code(self, ticket_number):
        query = "SELECT verification_code, name FROM ticketinfo WHERE ticket_number = %s"
        cursor.execute(query, (ticket_number))
        result = cursor.fetchone()
        if result is not None:
            return result
        else:
            return None

# 创建查票页面
class CheckTicketPage(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="查票页面", size=(400, 200))
        panel = wx.Panel(self)

        self.ticket_number_label = wx.StaticText(panel, label="票号:")
        self.ticket_number_text = wx.TextCtrl(panel)
        self.check_button = wx.Button(panel, label="查票")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.ticket_number_label, 0, wx.ALL, 5)
        sizer.Add(self.ticket_number_text, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.check_button, 0, wx.ALL | wx.CENTER, 5)

        panel.SetSizer(sizer)

        self.check_button.Bind(wx.EVT_BUTTON, self.on_check)

    def on_check(self, event):
        ticket_number = self.ticket_number_text.GetValue()

        # 在此处执行查票操作，从ticketinfo表中查询对应票号的信息
        query = "SELECT * FROM ticketinfo WHERE ticket_number = %s"
        values = (ticket_number,)
        cursor.execute(query, values)
        result = cursor.fetchone()

        if result:
            wx.MessageBox(f"票号: {result[2]}\n姓名: {result[1]}\n票型: {result[3]}\n检验码: {result[4]}\n操作员: {result[5]}\n入园日期: {result[6]}\n应付价格: {result[7]}\n优惠价格: {result[8]}\n实付价格: {result[9]}", "票务信息", wx.OK | wx.ICON_INFORMATION)
        else:
            wx.MessageBox("未找到对应票号的信息！", "错误", wx.OK | wx.ICON_ERROR)



# 创建应用程序对象
app = wx.App()

# 创建登录页面对象并显示
login_page = LoginPage()
login_page.Show()

# 运行应用程序
app.MainLoop()

'''本项目意在为已学的SQL指令，MySQL和wxPython做一个参考'''